package JsonInterface;

import HibernateFacet.second.*;
import ImplementInterface.Ad2ServiceImpl;
import ImplementInterface.ImplementAndroidInterface;
import com.message.source.SmsSDKDemo;
import com.opensymphony.xwork2.ActionSupport;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.SessionAware;
import org.apache.struts2.jasper.compiler.JspUtil;
import org.joda.time.DateTime;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.PUT;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.DatagramPacket;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class Ad2 extends ActionSupport implements ServletRequestAware, SessionAware {
    public HttpServletRequest request;
    public static Map<String,Integer> temporary = new HashMap<>();
    public static boolean isCreateSocket = false;
    public Ad2ServiceImpl ad2ServiceImpl;
    public JSONObject jMap;
    public static List list1 = new ArrayList<Map>();
    public static HashMap<String, Socket> socketMap2 = new HashMap<>();
    public static Integer num = 0;
    //public static byte[] responseBuf = new byte[1024];
    public static Map<String, byte[]> resMap = new ConcurrentHashMap<>();
    private Map<String, Object> result = new HashMap<>();

    public Map<String, Object> getResult() {
        return result;
    }

    public Ad2ServiceImpl getAd2ServiceImpl() {
        return ad2ServiceImpl;
    }

    public void setAd2ServiceImpl(Ad2ServiceImpl ad2ServiceImpl) {
        this.ad2ServiceImpl = ad2ServiceImpl;
    }

    @Override
    public void setSession(Map<String, Object> arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void setServletRequest(HttpServletRequest arg0) {
        // TODO Auto-generated method stub
        this.request = arg0;
    }

    public String createSocket() {
        System.out.println("hhh1");
        if (!isCreateSocket) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    isCreateSocket = true;
                    // next created TCP successfully
                    new SocketControl();

                }
            }).start();

        } else
            System.out.print("TCP socket is created!");

        return SUCCESS;

    }


    public String RemoteOpening() {

        try {
            String address_str = request.getParameter("number");
            String pwd = request.getParameter("pwd");

            System.out.println("address:" + address_str);
            int i1 = ad2ServiceImpl.checkDevicePWd(address_str, pwd);
            if (i1==-1) {
                result.put("code", "201");
                result.put("message", "设备密码错误");
                return ERROR;
            }
            if (!address_str.isEmpty()) {
                System.out.println("远程分闸");
                Socket socket = null;
                if (socketMap2.size() != 0) {
                    System.out.println("hhh");
                    for (Map.Entry<String, Socket> stringSocketEntry : socketMap2.entrySet()) {
                        if (stringSocketEntry.getKey().equals(address_str)) {
                            socket = stringSocketEntry.getValue();
                            if (socket != null && !socket.isClosed()) {
                                // 向当前连接的 socket 发送 byte[] 数据
                                OutputStream out = socket.getOutputStream();
                                char[] c = address_str.toCharArray();
                                byte[] a = new byte[c.length];
                                for (int i = 0; i < c.length; i++) {
                                    a[i] = (byte) (c[i] - '0' + 0x30);
                                }
                                byte[] buf = new byte[]{a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], (byte) 0x10, (byte) 0x01, (byte) 0x20, 0, 0};
                                int crc = CRC16.getCRC1021(buf, buf.length - 2);
                                int ch = (int) (crc >> 8) & 0xff;
                                int cl = (int) crc & 0xff;
                                buf[buf.length - 2] = (byte) ch;
                                buf[buf.length - 1] = (byte) cl;
                                // 发送数据和接收数据逻辑
                                out.write(buf);
                                out.flush();
                                System.out.println("数据已发送: ");
                                for (int k = 0; k < buf.length; k++) {
                                    System.out.print((Integer.toHexString(buf[k] & 0xff)) + " ");
                                }
                                System.out.println();
                               /* if ((responseBuf[0] & 0xff) == (0x06 & 0xff) && (responseBuf[1] & 0xff) == (0x4F & 0xff) && (responseBuf[2] & 0xff) == (0x4B & 0xff)) {
                                    System.out.println("okokokok2");
                                    Arrays.fill(responseBuf, (byte) 0);
                                    result.put("status", "success2");
                                    return SUCCESS;
                                }else {
                                    result.put("status", "error");
                                    return ERROR;
                                }*/
                                //需要延迟执行的业务数据
                                // 接收响应数据
                                /*InputStream in = socket.getInputStream();
                                byte[] responseBuf = new byte[1024]; // 假设响应长度最大为 1024 字节
                                int bytesRead = in.read(responseBuf);
                                if (bytesRead > 0) {
                                    System.out.println("\n收到响应数据: ");
                                    for (int i = 0; i < bytesRead; i++) {
                                        System.out.print((Integer.toHexString(responseBuf[i] & 0xff)) + " ");
                                    }
                                    if ((responseBuf[0] & 0xff) == (0x06 & 0xff) && (responseBuf[1] & 0xff) == (0x4F & 0xff) && (responseBuf[2] & 0xff) == (0x4B & 0xff)) {
                                        System.out.println("okokokok");
                                    }
                                    // 处理响应数据
                                }*/
                                result.put("code", "200");
                                return SUCCESS;
                            } else {
                                System.out.println("Socket 已关闭或不可用");
                            }
                            break;
                        }
                    }
                } else {
                    System.out.println("没有可用的 socket 连接");
                    result.put("code", "201");
                    result.put("message", "设备未连接");
                    return ERROR;
                }
            }

        } catch (IOException e) {
            System.out.println("发送数据时发生错误: " + e.getMessage());
            // 发生错误，返回 error
            result.put("code", "201");
            result.put("message", "网络出错了，分闸失败");
            return ERROR;
        }
        result.put("code", "201");
        return ERROR;
    }
    //设置额定电流
    public String updateCurrentRating() {
        try {
            String address_str = request.getParameter("number");
            String electricity = request.getParameter("electricity");
            int electricity2 = Integer.parseInt(electricity);
            System.out.println("number:" + address_str);
            System.out.println("electricity:" + electricity);

               /* 0x40:6A  0x41:10A  0x42:16A
                0x43:20A  0x44:25A  0x45:32A  0x46:40A  0x47:50A  0x48:63A*/
            byte number = 0x00;
            switch (electricity2) {
                case 6:
                    //语句
                    number = 0x40;
                    break; //可选
                case 10:
                    number = 0x41;
                    //语句
                    break; //可选
                case 16:
                    number = 0x42;
                    //语句
                    break;
                case 20:
                    number = 0x43;
                    //语句
                    break;
                case 25:
                    number = 0x44;
                    //语句
                    break; //可选
                case 32:
                    number = 0x45;
                    //语句
                    break;
                case 40:
                    number = 0x46;
                    //语句
                    break;
                case 50:
                    number = 0x47;
                    //语句
                    break;
                case 63:
                    number = 0x48;
                    //语句
                    break;
            }
            if (number == 0x00) {
                System.out.println("设置参数不对");
                result.put("code", 201);
                result.put("message", "设置额定电流的数值不符");
                return ERROR;
            }
            if (!address_str.isEmpty()) {
                System.out.println("远程设定额定电流");
                Socket socket = null;
                if (socketMap2.size() != 0) {
                    System.out.println("hhh");
                    for (Map.Entry<String, Socket> stringSocketEntry : socketMap2.entrySet()) {
                        if (stringSocketEntry.getKey() !=null && stringSocketEntry.getKey().equals(address_str)) {
                            socket = stringSocketEntry.getValue();
                            if (socket != null && !socket.isClosed()) {
                                // 向当前连接的 socket 发送 byte[] 数据
                                OutputStream out = socket.getOutputStream();
                                char[] c = address_str.toCharArray();
                                byte[] a = new byte[c.length];
                                for (int i = 0; i < c.length; i++) {
                                    a[i] = (byte) (c[i] - '0' + 0x30);
                                }
                                byte[] buf = new byte[]{a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], (byte) 0x10, (byte) 0x01, number, 0, 0};
                                int crc = CRC16.getCRC1021(buf, buf.length - 2);
                                int ch = (int) (crc >> 8) & 0xff;
                                int cl = (int) crc & 0xff;
                                buf[buf.length - 2] = (byte) ch;
                                buf[buf.length - 1] = (byte) cl;

                                // 发送数据和接收数据逻辑
                                out.write(buf);
                                out.flush();

                                // 处理响应
                                System.out.println("数据已发送: ");
                                for (int k = 0; k < buf.length; k++) {
                                    System.out.print((Integer.toHexString(buf[k] & 0xff)) + " ");
                                }
                                System.out.println();
                                Thread.currentThread().sleep(3000);
                                if (resMap.containsKey(address_str)) {
                                    System.out.println("======================");
                                    for (Map.Entry<String, byte[]> entry : resMap.entrySet()) {
                                        System.out.println(entry.getKey()+ "=" + Arrays.toString(entry.getValue()));
                                    }
                                    System.out.println("======================");
                                    byte[] responseBuf = resMap.get(address_str);
                                    if ((responseBuf[0] & 0xff) == (0x06 & 0xff) && (responseBuf[1] & 0xff) == (0x4F & 0xff) && (responseBuf[2] & 0xff) == (0x4B & 0xff)) {
                                        System.out.println("okokokok3");
                                        Arrays.fill(responseBuf, (byte) 0);
                                        System.out.println("jjjjjjjjjjjjjj");
                                        for (Map.Entry<String, byte[]> entry : resMap.entrySet()) {
                                            System.out.println(entry.getKey()+ "=" + Arrays.toString(entry.getValue()));
                                        }
                                        System.out.println("j2j2j2j2jj22j2j2");
                                        ad2ServiceImpl.updateCurrentRating(address_str,electricity2);
                                        result.put("code", 200);
                                        return SUCCESS;
                                    } else {
                                        result.put("code", "201");
                                        result.put("message", "设备响应不符,修改失败");
                                        return ERROR;
                                    }
                                }
                            } else {
                                System.out.println("Socket 已关闭或不可用");
                            }
                            break;
                        }
                    }
                } else {
                    System.out.println("没有可用的 socket 连接");
                    result.put("code", 201);
                    result.put("message", "设备未连接,请稍后再试");
                    return ERROR;
                }
            }
        } catch (IOException e) {
            System.out.println("发送数据时发生错误: " + e.getMessage());
            // 发生错误，返回 error
            result.put("code", 201);
            result.put("message", "网络出错了，数据发送失败");
            return ERROR;
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        result.put("code", 201);
        result.put("message", "设备无响应");
        return ERROR;
    }

    public String findConnectNum() {
        String userId = request.getParameter("userId");
        //get deivceNumber  if map.equals  num++  return num
        int num = 0;
        List<String> userDeviceNumber = ad2ServiceImpl.findUserDeviceNumber(Integer.parseInt(userId));
        for (String s : userDeviceNumber) {
            if (socketMap2.containsKey(s)){
                num++;
            }
        }
        int userDeviceNum = ad2ServiceImpl.findUserDeviceNum(Integer.parseInt(userId));
        result.put("code",200);
        result.put("num",userDeviceNum);
        result.put("connectNum", num);
        return SUCCESS;
    }

    public String checkDeviceConnect() {
        String number = request.getParameter("number");
        boolean b = socketMap2.containsKey(number);
        result.put("status",b);
        return SUCCESS;
    }

    //所有设备的总功率
    public String findUserDeviceSumPower() {
        String userId = request.getParameter("userId");
        int userDeviceSumPower = ad2ServiceImpl.findUserDeviceSumPower(Integer.parseInt(userId));

        result.put("code",200);
        result.put("sumPower",userDeviceSumPower);
        return SUCCESS;
    }

    public String findUseElectricity() {
        //当前用户的设备今年所有用电量
        String userId = request.getParameter("userId");
        String type = request.getParameter("type");
        if (type!= null && type.equals("1")) {
            DateTime dateTime = new DateTime();
            int year = dateTime.getYear();
            String s1 = year + "-01-01";
            String s2= (year+1) + "-01-01";

            System.out.println(userId);
            System.out.println(s1);
            System.out.println(s2);
            ElectricityData userDeviceUseElectricity = ad2ServiceImpl.findUserDeviceUseElectricity(Integer.parseInt(userId), s1, s2);
            result.put("electricity",userDeviceUseElectricity);
            result.put("code",200);
            return SUCCESS;
        } else if (type!= null && type.equals("2")) {
            String d1 = request.getParameter("d1");
            String d2 = request.getParameter("d2");
            ElectricityData userDeviceUseElectricity = ad2ServiceImpl.findUserDeviceUseElectricity(Integer.parseInt(userId), d1, d2);
            result.put("electricity",userDeviceUseElectricity);
            result.put("code",200);
            return SUCCESS;
        }
        result.put("code",201);
        return ERROR;
    }

    public String findDeviceUseElectricity() {
        //当前设备用电量
        String deviceId = request.getParameter("deviceId");
        String type = request.getParameter("type");
        if (type!= null && type.equals("1")) {
            //本月用电量
            DateTime dateTime = new DateTime();
            int year = dateTime.getYear();
            int monthOfYear = dateTime.getMonthOfYear();
            String s1 = year + "-" +  monthOfYear + "-01-01";
            String s2= year + "-" +  (monthOfYear+1) + "-01-01";;

            System.out.println(deviceId);
            System.out.println(s1);
            System.out.println(s2);
            ElectricityData DeviceUseElectricity = ad2ServiceImpl.findDeviceUseElectricity(Integer.parseInt(deviceId), s1, s2);
            result.put("electricity",DeviceUseElectricity);
            result.put("code",200);
            return SUCCESS;
        } else if (type!= null && type.equals("2")) {
            String d1 = request.getParameter("d1");
            String d2 = request.getParameter("d2");
            ElectricityData DeviceUseElectricity = ad2ServiceImpl.findDeviceUseElectricity(Integer.parseInt(deviceId), d1, d2);
            result.put("electricity",DeviceUseElectricity);
            result.put("code",200);
            return SUCCESS;
        }
        result.put("code",201);
        return ERROR;
    }
    //设备故障数量
    public String findFaultNum() {
        String userId = request.getParameter("userId");
        Integer faultNum = ad2ServiceImpl.findFaultNum(Integer.parseInt(userId));
        result.put("code",200);
        result.put("faultNum",faultNum);
        return SUCCESS;
    }

    public String findOneWarning() {
        String userId = request.getParameter("userId");
        String type = request.getParameter("type");
        if (type.equals("1")) {
            Warning oneWarning = ad2ServiceImpl.findOneWarning(Integer.parseInt(userId));
            result.put("code",200);
            result.put("warning",oneWarning);
        }else if (type.equals("2")) {
            String d1 = request.getParameter("d1");
            String d2 = request.getParameter("d2");
            List<Warning> userWarning = ad2ServiceImpl.findUserWarning(Integer.parseInt(userId), d1, d2);
            result.put("code",200);
            result.put("warning",userWarning);
        }
        return SUCCESS;

    }

    public String findDeviceWarning() {
        String deviceId = request.getParameter("deviceId");
        String type = request.getParameter("type");
        int did = Integer.parseInt(deviceId);
        if (type.equals("1")) {
            Warning oneWarning = ad2ServiceImpl.findDeviceWarning(did);
            result.put("code",200);
            result.put("warning",oneWarning);
        }else if (type.equals("2")) {
            String d1 = request.getParameter("d1");
            String d2 = request.getParameter("d2");
            List<Warning> userWarning = ad2ServiceImpl.findDeviceWarnings(did, d1, d2);
            result.put("code",200);
            result.put("warning",userWarning);
        }
        return SUCCESS;
    }

    public String findDevice() {
        String userId = request.getParameter("userId");
        List<Device> devices = ad2ServiceImpl.findDeviceByUserId(Integer.parseInt(userId));
        result.put("code",200);
        result.put("devices",devices);
        return SUCCESS;
    }

    public String findDeviceInfo(){
        String deviceId = request.getParameter("deviceId");
        int did = Integer.parseInt(deviceId);
        Device device = ad2ServiceImpl.findDeviceInfoById(did);
        DeviceData deviceData = ad2ServiceImpl.findDeviceData(did);
        result.put("code",200);
        result.put("device",device);
        result.put("deviceData",deviceData);
        return SUCCESS;
    }

    public String sendCaptcha() {
        final int Captcha = new Random().nextInt(1000000) + 1;
        String phone_number;
        String name = request.getParameter("name");
        if (!StringUtils.isBlank(name)) {
            phone_number = ad2ServiceImpl.findUserPhoneByName(name);
        }else {
            phone_number = request.getParameter("phone");
        }
        temporary.put(phone_number, Captcha);
        System.out.println("verify of register:" + phone_number + "/" + Captcha);
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000 * 60);
                    System.out.println("Clean of map:" + phone_number + "/" + Captcha);
                    temporary.remove(phone_number);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }).start();
        SmsSDKDemo d = new SmsSDKDemo();
        d.messageClient(phone_number, Captcha);
        result.put("code",200);
        return SUCCESS;
    }
    /*public Boolean judgmentCaptcha(String phone,Integer captcha) {
        Integer code = temporary.get(phone);
        System.out.println("输入的验证码=" +captcha);
        System.out.println("验证码code=" + code);
        boolean b = Objects.equals(code, captcha);
        return b;
    }*/

    public String registered() {
        String name = request.getParameter("name");
        String password = request.getParameter("password");
        String phone = request.getParameter("phone");
        String captcha = request.getParameter("captcha");
        Integer captcha2 = Integer.parseInt(captcha);
        Integer code = temporary.get(phone);

        boolean b = Objects.equals(code, captcha2);
        if (!b) {
            result.put("code",201);
            result.put("msg","请输入正确的验证码");
            return SUCCESS;
        }
        Pattern compile = Pattern.compile("[0-9a-zA-z]+");
        Matcher matcher = compile.matcher(password);
        boolean b2 = matcher.matches();
        if (!b2) {
            result.put("code",201);
            result.put("msg","密码格式不符合");
            return SUCCESS;
        }
        int registered = ad2ServiceImpl.registered(name, password, phone);

        if (registered == -1) {
            result.put("code",201);
            result.put("msg","注册失败,账号或手机号重复");
        }
        result.put("code",200);
        return SUCCESS;
    }

    public String forgetPassword() {
        String name = request.getParameter("name");
        String password = request.getParameter("password");
        String captcha = request.getParameter("captcha");
        Integer captcha2 = Integer.parseInt(captcha);

        String phone = ad2ServiceImpl.findUserPhoneByName(name);
        Integer code = temporary.get(phone);
        if (code == null) {
            result.put("code",201);
            result.put("msg","验证码已失效");
            return SUCCESS;
        }
        boolean b = Objects.equals(code, captcha2);
        if (!b) {
            result.put("code",201);
            result.put("msg","请输入正确的验证码");
            return SUCCESS;
        }
        Pattern compile = Pattern.compile("[0-9a-zA-z]+");
        Matcher matcher = compile.matcher(password);
        boolean b2 = matcher.matches();
        if (!b2) {
            result.put("code",201);
            result.put("msg","密码格式不符合");
            return SUCCESS;
        }
        int registered = ad2ServiceImpl.updateUserPwd(name, password);

        if (registered == -1) {
            result.put("code",201);
            result.put("msg","密码更新失败");
        }
        result.put("code",200);
        return SUCCESS;
    }

    public  String login() {
        String name = request.getParameter("name");
        String password = request.getParameter("password");
        User login = ad2ServiceImpl.login(name, password);
        if (login!=null) {
            result.put("code",200);
            result.put("user",login);
            return SUCCESS;
        }
        result.put("code",201);
        return SUCCESS;
    }
    public String addDevice() {
        Integer userId = Integer.parseInt(request.getParameter("userId"));
        String number = request.getParameter("number");
        int i = ad2ServiceImpl.addDevice(userId, number);
        if (i!=-1) {
            result.put("status",true);
            return SUCCESS;
        }
        result.put("status",false);
        return SUCCESS;
    }
}
